import { Connection as JsforceConnection } from 'jsforce';
import { getApi, SalesforceAPI } from './api';

export const connectToSalesforce = (credentials: SalesforceCredentials): SalesforceConnection => {
  return new SalesforceConnectionImpl(credentials);
};

export interface SalesforceCredentials {
  username: string;
  password: string;
  loginUrl: string;
}

export interface SalesforceConnection {
  api(): SalesforceAPI | PromiseLike<SalesforceAPI>;
}

class SalesforceConnectionImpl implements SalesforceConnection {
  private jsfConnection: JsforceConnection;
  private isLoggedIn: boolean;

  constructor(private readonly credentials: SalesforceCredentials) {
    this.jsfConnection = new JsforceConnection({
      loginUrl: this.credentials.loginUrl,
    });
    this.isLoggedIn = false;
  }

  async api(): Promise<SalesforceAPI> {
    await this.login();
    return getApi(this.jsfConnection);
  }

  private async login() {
    if (!this.isLoggedIn) {
      this.isLoggedIn = true;
      await this.jsfConnection.login(this.credentials.username, this.credentials.password);
    }
  }
}
